import { Browser, Page } from "puppeteer";
import { createBrowserPage } from "../browser";
import { lock, unLock, waitFor, waitUnLock } from "@nodejs/redis";
import { ProxyUser, useEntityManager } from "../entities";
import { ProxyCookies, ProxyUserStatus, ProxyUserType } from "../entities/browser";
import { v4 } from "uuid";
import { Loginer } from "./Loginer";
export class JdLoginer extends Loginer {
    start() {
        return new Promise<void>(async (resolve, reject) => {
            let page: Page | null = null;
            let browser: Browser | null = null;
            try {
                const url = `https://www.jd.com/`
                const [_page, _browser] = await createBrowserPage(this.clientId, url, {
                    onResponse: async r => {
                        const url = r.url()
                        if (url.includes('https://qr.m.jd.com/show')) {
                            const _ = new URL(url)
                            if (_.searchParams.get('appid')) {
                                const image = await r.buffer()
                                await lock(this.reqId, image.toString('utf8'))
                            }
                        }
                        if (url.startsWith('https://passport.jd.com/uc/qrCodeTicketValidation')) {
                            console.log(`qrCodeTicketValidation`)
                            const json = await r.json()
                            console.log({ json })
                        }
                    }
                });
                page = _page;
                browser = _browser;
                const loginBtn = await page.waitForSelector('a.link-login').catch(e => {
                    return null;
                });
                if (!loginBtn) return reject(new Error(`login btton not found`))
                await loginBtn.click();
                await page.waitForNavigation().catch(e => console.log(`wait for navigation error: ${e.message}`))
                const qrcodeBtn = await page.waitForSelector('a[clstag="pageclick|keycount|passport_main|click_qrcode_login"]')
                if (!qrcodeBtn) return reject(new Error(`login qrcode button not found`))
                await qrcodeBtn.click()
                // const qrcodeImage = await page.waitForSelector(`#passport-main-qrcode-img`)
                // if (!qrcodeImage) return reject(new Error(`qrcode image not found`))
                await this.qrcode();
                console.log(`登陆二维码获取成功`)
                // 等待扫码登陆
                await waitUnLock(this.reqId)
                console.log(`确认扫码成功`)
                const uid = await waitFor(`uid.${this.reqId}`)
                await page.goto(`https://weibo.com/u/${uid}`, { waitUntil: 'networkidle2' })
                // 获取用户信息
                const userInfo = await waitFor(`userInfo.${this.reqId}`)
                await unLock(`userInfo.${this.reqId}`)
                // 保存信息到数据库
                await useEntityManager(async m => {
                    const { ok, data } = userInfo;
                    if (ok === 1) {
                        const user = data.user;
                        const uid = `${user.idStr || user.id}`
                        const item = await m.findOne(ProxyUser, { where: { type: ProxyUserType.WEIBO, uid: uid } })
                        const u = m.create(ProxyUser, {
                            uuid: item?.uuid || v4(),
                            status: ProxyUserStatus.ONLINE,
                            uid: user.idstr || user.id,
                            avatar: user.avatar_hd || user.avatar_large || user.cover_image_phone,
                            type: ProxyUserType.WEIBO,
                            info: user,
                            login_at: this.clientId
                        })
                        await m.save(ProxyUser, u)
                        if (page) {
                            // 获取cookies信息
                            const cookies = await page.cookies()
                            const olds = await m.find(ProxyCookies, { where: { user_id: u.uuid } })
                            const list = cookies.map(c => {
                                const old = olds.find(it => it.name === c.name && it.domain === c.domain && it.path === c.path)
                                return m.create(ProxyCookies, {
                                    id: old?.id,
                                    user_id: u.uuid,
                                    ...c,
                                    expires: c.expires * 1000 * 1000 * 10
                                })
                            })
                            await m.save(ProxyCookies, list)
                        }
                    }
                })
            } catch (e) {
                return reject(e)
            } finally {
                if (browser) {
                    const pages = await browser.pages()
                    await Promise.all(pages.map(p => p.close()))
                    await browser.close()
                }
            }
        })
    }
}
